/**
 * yeganaaa@163.com
 * author: (مۇختەرجان مەخمۇت) muhtaer mahmood
 * 10/13/2019, 1:40:26 PM GMT+06:00
 */


import { RpcBridgeHost } from "./Rpc";
import * as WebSocket from "ws"
import { isNodeRuntime } from "./Helper";

class WebSocketRpcBridgeHost extends RpcBridgeHost<WebSocket> {
    public socket: WebSocket = null!
    public constructor(private socketCreator: () => Promise<WebSocket>) {
        super()
    }

    initialize(): Promise<void> {
        return new Promise<void>(async (resolve, reject) => {
            this.socket = await this.socketCreator()
            this.socket.onerror = error => {
                this.onError(error as any)
                reject(error)
            }
            this.socket.onclose = event => this.onClosed()
            this.socket.onmessage = async data => {
                if (data.data.constructor.name == "Blob")
                    this.onMessageReceived((await (data.data as any).arrayBuffer()) as Uint8Array)
                else
                    this.onMessageReceived((await data.data) as Uint8Array)
            }
            const onOpen = () => {
                this.onConnected()
                resolve()
            }
            this.socket.onopen = (event) => {
                if (!isNodeRuntime()) onOpen()
            }
            if (isNodeRuntime()) setTimeout(() => onOpen(), 0)
        })
    }

    close(callback: () => void): void {
        this.socket.close()
        callback()
    }
    send(data: Uint8Array, callback: (error: Error) => void): void {
        this.socket.send(data, error => callback(error!))
    }
}

export { WebSocketRpcBridgeHost }
